package com.atguigu.gulimall.search.thread;

import java.util.concurrent.*;

/**
 * @author : wenchao.long
 * @date : Created in 2021/8/5 9:26 周四
 * @description : value
 *         <p>
 *         七大参数
 *         corePoolSize: 核心线程数 线程池创建好以后就准备就绪的线程数量 就等待来接受异步任务去执行
 *         maximumPoolSize: 最大线程数 控制资源
 *         keepAliveTime: 存活时间 当线程数大于核心数时，这是多余的空闲线程在终止前等待新任务的最长时间。(maximumPoolSize - corePoolSize)
 *         unit: 时间单位
 *         workQueue: 阻塞队列 如果任务有很多 就会将目前多的任务放在队列里面 只要有线程空闲，就会去队列里面取出新的任务去执行
 *         threadFactory: 线程的创建工厂
 *         handler: 如果队列满了 按照我们指定的拒绝策略拒绝执行任务
 *         <p>
 *         工作顺序
 *         1. 线程池创建 准备好core数量的核心线程 准备执行任务
 *         1.1core满了 就将进来的任务翻入阻塞队列中 空闲了core 就拿阻塞队列执行
 *         1.2 阻塞队列满了 就直接开新线程执行 最大只能开到max指定的数量
 *         1.3 max满了就用 handler拒绝任务
 *         1.4 max都执行完成 有很多空闲 在指定的时间keepAliveTime以后 释放 max-core这些线程
 */
public class ThreadTest {

    public static ExecutorService service = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        /*
        1. 继承Thread
        2. 实现Runnable接口
        3. 实现Callable接口 + FutureTask (可以拿到返回结果 可以处理异常)
        4. 线程池

        区别
        1/2 不能得到返回值
        3 可以获取返回值
        1,2,3 都不能控制资源
        4 可以控制资源  性能稳定
        一个线程 core 7 max 20 queue 50 ；100并发进来怎么分配

        7个立刻得到执行，50个会进入队列，再开13个进行执行
        剩下的30个就使用拒绝策略
        如果不想丢弃 就使用CallerRunsPolicy
         */

        /*
        创建线程池
        1. Executors.newFixedThreadPool(10); service.execute(new Runnable01());
        2. ThreadPoolExecutor executor = new ThreadPoolExecutor();
         */

        System.out.println("main....start...");

        //======================
        /* 1.
        new Thread01().start();
        */

        //======================
        /* 2.
        new Thread(new Runnable01()).start();
        */

        //======================
        /* 3.
        FutureTask<Integer> futureTask = new FutureTask<>(new Callable01());
        new Thread(futureTask).start();

        // 等待整个线程执行完成，获取返回结果 是阻塞等待
        Integer integer = futureTask.get();
        System.out.println(integer);*/

        // 给线程池直接提交任务

        // 在业务代码里面 以上三种启动线程的方式都不用
        // [将所有的多线程异步任务都交给线程执行]

        // 当前系统中 池只有一两个 每一个异步任务 提交给线程池 让他自己去执行

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(100000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());


        // core 为 0 所有都可回收
        //Executors.newCachedThreadPool();
        // 固定大小 core = max 都不可回收
        // Executors.newFixedThreadPool(10);
        // 定时任务的线程池
        //Executors.newScheduledThreadPool(10);
        // 单线程的线程池 后台从队列里面获取任务 挨个执行
        //Executors.newSingleThreadScheduledExecutor();


        System.out.println("main....end...");
    }

    public static class Thread01 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
        }
    }

    public static class Runnable01 implements Runnable {
        @Override
        public void run() {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
        }
    }

    public static class Callable01 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            System.out.println("当前线程：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果：" + i);
            return i;
        }
    }


}
